/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bookDatabase_pkg;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.Writer;

public class bookDatabaseDriver {

    /**
     * Global variable for transferring data between methods
     */
    static String[] FILEARRAY;

    //Test method below (to be used in eclipse):
//    public static void main(String[] args) {
//        int success1 = createCategoryDB("action");
//        System.out.println("1: " + success1);
//
//        int success4 = databaseConnect("action");
//        System.out.println("2: " + success4);
//        String success5 = addBook("12345", "Spiderman", "Hello!", "1.99");
//        System.out.println("3: " + success5);
//        String success6 = addBook("54321", "The Hulk", "Green", "4.99");
//        System.out.println("4: " + success6);
//
//        String[] all = getBook("12345");
//        System.out.println("5: " + all[1]);
//
//        deleteDB("action");
//    }

    // CREATE DIRECTORY
    /**
     * Method called to create a sub-directory at the current directory of name
     * 'dirname'
     *
     * @param dirname
     *            Name of directory to be created
     * @return 0 for successful completion; -1 for failure
     */
    private static int createDir(String dirname) {
        try {
            boolean success = (new File(dirname).mkdirs());
            if (success) {
                return 0;
            } else {
                return -1;
            }
        } catch (Exception e) {
            return -1;
        }
    }

    // DELETE DIRECTORY
    /**
     * Method called to delete a sub-directory at the current directory of name
     * 'dirname'
     *
     * @param dirname
     *            Name of directory to be deleted
     * @return 0 for successful completion; -1 for failure
     */
    private static int deleteDir(String dirname) {
        try {
            boolean success = (new File(dirname).delete());
            if (success) {
                return 0;
            } else {
                return -1;
            }
        } catch (Exception e) {
            return -1;
        }
    }

    // CREATE FILE
    /**
     * Method called to create a text file named by 'filename' in the directory
     * given by 'dirname'
     *
     * @param filename
     *            Name of file to be created
     * @param dirname
     *            Name of directory where file is to be created
     * @return 0 for successful completion; -1 for failure
     */
    private static int createFile(String filename, String dirname) {
        try {
            createDir(dirname);
            File f = new File(dirname, filename + ".txt");
            if (!f.exists()) {
                f.createNewFile();
                return 0;
            } else {
                return -1;
            }
        } catch (Exception e) {
            return -1;
        }
    }

    // DELETE FILE
    /**
     * Method called to delete a text file named by 'filename' in the directory
     * given by 'dirname'
     *
     * @param filename
     *            Name of file to be deleted
     * @param dirname
     *            Name of directory to be deleted
     * @return 0 for successful completion; -1 for failure
     */
    private static int deleteFile(String filename, String dirname) {
        try {
            File f = new File(dirname, filename + ".txt");
            if (f.exists()) {
                f.delete();
                deleteDir(dirname);
                return 0;
            } else {
                return -1;
            }
        } catch (Exception e) {
            return -1;
        }
    }

    // WRITE TO FILE
    /**
     * Method called to append data to a given file of 'filename'.txt
     *
     * @param data
     *            Data to be written
     * @param filename
     *            Name of file to be written to
     * @param dirname
     *            Name of directory file to be written to is in
     * @return 0 for successful completion; -1 for failure
     */
    private static int writeToFile(String data, String filename, String dirname) {
        try {
            createFile(filename, dirname);
            Writer output = new BufferedWriter(new FileWriter("./" + dirname
                    + "/" + filename + ".txt", true));
            output.write(data + "\n");
            output.close();
            return 0;
        } catch (Exception e) {
            return -1;
        }
    }

    // READ FROM FILE
    /**
     * Method called to read data from a file given a unique ID
     *
     * @param uniqueID
     *            Term to search for
     * @param filename
     *            Name of file to read from
     * @param dirname
     *            Name of directory file to be read is in
     * @return 0 for successful completion; -1 for failure
     */
     private static int readFromFile(String uniqueID, String filename, String dirname) {
        try {
            FileInputStream fstream = new FileInputStream("./" + dirname + "/"
                    + filename + ".txt");
            DataInputStream in = new DataInputStream(fstream);
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            String strLine;
            int i = 0;
            String[] fileArray = new String[0];
            while ((strLine = br.readLine()) != null) {
                if (strLine.contains(uniqueID) == true
                        || uniqueID.equals("printAll")) {
                    String[] newFileArray = new String[fileArray.length + 1];
                    int j = 0;
                    while (j < fileArray.length) {
                        newFileArray[j] = fileArray[j];
                        j++;
                    }
                    newFileArray[i] = strLine;
                    fileArray = newFileArray;
                    i++;
                }
            }
            FILEARRAY = new String[fileArray.length];
            int j = 0;
            while (j < FILEARRAY.length) {
                FILEARRAY[j] = fileArray[j];
                j++;
            }
            in.close();
            return 0;
        } catch (Exception e) {
            return -1;
        }
    }

    /****************************************************************************************************************************/
    /** Declare global variables: */
    static String SERVICENAME = "bookDatabase";
    static String CATEGORY = null;
    static Boolean CLIENTCONNECTED = false;

    // CREATE CATEGORY
    /**
     * This method is called to set up a database on the service. This must be
     * called else the service will not connect as it has no database to store
     * data on.
     *
     * Method returns 0 if the client database is created for the first time and
     * -1 if there is already a client database that matches category on the
     * service.
     *
     * @param category
     *            Unique ID of the client
     * @return 0 for successful completion; -1 for failure
     */
    public static int createCategoryDB(String category) {
        try {
            int success = createFile(category  + "Database", SERVICENAME);
            if (success == 0) {
                return 0;
            } else {
                return -1;
            }
        } catch (Exception e) {
            return -1;
        }
    }

    // CONNECT CATEGORY
    /**
     * This method must be called whenever the client connects to the service.
     * This method is used to connect to the database that corresponds with the
     * clientâ€™s category.
     *
     * ClientID must be the same whenever the client connects to the service
     * otherwise the database will not be found.
     *
     * Method returns 0 on success and -1 on error. If -1 is returned then
     * either the category is wrong or the client has not created a database,
     * call createClientDB() if this is the case.
     *
     * @param category
     *            Unique ID of the client
     * @return 0 for successful completion; -1 for failure
     */
    public static int databaseConnect(String category) {
        try {
            int success = createFile(category  + "Database", SERVICENAME);
            if (success != 0) {
                CATEGORY = category  + "Database";
                CLIENTCONNECTED = true;
                return 0;
            } else {
                deleteFile(category  + "Database", SERVICENAME + category);
                return -1;
            }
        } catch (Exception e) {
            return -1;
        }
    }

    /****************************************************************************************************************************/
    // Add a book to the database
    /**
     * This method is used to add a book to the database
     *
     * â€œBook savedâ€ is returned on success. â€œBook not savedâ€ if there is
     * a problem connecting to the database. â€œClient not connectedâ€ is returned
     * if databaseConnect() has not been called upon connecting to the server.
     *
     * @param ISBN
     *            Unique identifier
     * @param title
     *            Title of the book
     * @param description
     *            Description of the book
     * @param price
     *            Current price of the book
     * @return String containing "Book saved" for success;
     *         "Book not saved" or "Client not connected" on failure
     */
    public static String addBook(String ISBN,String title,String description,String price) {
        if (CLIENTCONNECTED == true) {
            String data = ISBN + "\t" + title + "\t" + description + "\t" + price;
            int successful = writeToFile(data, CATEGORY, SERVICENAME);

            if (successful == 0) {
                /** Return confirmation message */
                return "Book saved";
            } else {
                /** Return error message */
                return "Book not saved";
            }
        } else {
            /** Return error message */
            return "Client not connected";
        }
    }

    // Return all books in file
    /**
     * When this method is called it returns a String array of all the records
     * stored on the database. A record is in the form â€œuserID,
     * itemID,feedbackStringâ€. On fail it returns a string array with only one
     * string in it. If databaseConnect() was not run then this string will read
     * â€œClient not connectedâ€ else if the file was not read then the string will
     * read â€œFile not readâ€.
     *
     * @return An array, where each block contains a feedback article; returns
     *         String[0] as either "File not read" or "Client not connected" on
     *         failure
     */
    public static String[][] getAllBooks() {
        if (CLIENTCONNECTED == true) {
            int successful = readFromFile("printAll", CATEGORY,
                    SERVICENAME);
            if (successful == 0) {
                String[][] returnArray = new String[FILEARRAY.length][4];

                // Loops through records
                for(int i=0; i<FILEARRAY.length; i++){
                    // Loops through fields in the record i
                    char current;

                    String ISBN = "";
                    String title = "";
                    String description = "";
                    String price = "";

                    int fieldCount = 0;
                    for(int j=0; j<FILEARRAY[i].length(); j++){

                        current = FILEARRAY[i].charAt(j);

                        if(current != '\t'){
                            // add to ISBN
                            if(fieldCount == 0){
                                ISBN = ISBN.concat(String.valueOf(current));
                            }
                            // add to title
                            else if(fieldCount == 1){
                                title = title.concat(String.valueOf(current));
                            }
                            // add to description
                            else if(fieldCount == 2){
                                description = description.concat(String.valueOf(current));
                            }
                            // add to price
                            else if(fieldCount == 3){
                                price = price.concat(String.valueOf(current));
                            }
                        }
                        else if(current == '\t'){
                            fieldCount++;
                        }

                    }
                    // add fields to returnArray
                    returnArray[i][0] = ISBN;
                    returnArray[i][1] = title;
                    returnArray[i][2] = description;
                    returnArray[i][3] = price;
                }

                return returnArray;
            } else {
                /** Return error message */
                String[][] error1 = new String[1][0];
                error1[0][0] = "File not read";
                return error1;
            }
        } else {
            /** Return error message */
            String[][] error2 = new String[1][0];
            error2[0][0] = "Client not connected";
            return error2;
        }
    }

    // Search for a book with the given ISBN
    // If record does not exist then null will be returned
    /**
     * When this method is called it returns a String array of all the books
     * stored on the database that match the search parameter â€œISBNâ€.
     * On fail it returns a string array with only one string in it.
     * If databaseConnect() was not run then this string will read â€œClient not
     * connectedâ€ else if the file was not read then the string will read
     * â€œFile not readâ€.
     *
     * @param ISBN
     *            Unique ID to specify the book being looked for
     * @return An array, where each block contains a book article; returns
     *         String[0] as either "File not read" or "Client not connected" on
     *         failure
     */
    public static String[] getBook(String ISBN) {
        if (CLIENTCONNECTED == true) {
            int successful = readFromFile(ISBN, CATEGORY,
                    SERVICENAME);
            if (successful == 0) {
                String[] returnArray = new String[4];

                // Loops through records
                for(int i=0; i<FILEARRAY.length; i++){
                    // Loops through fields in the record i
                    char current;

                    String ISBN1 = "";
                    String title = "";
                    String description = "";
                    String price = "";

                    int fieldCount = 0;
                    for(int j=0; j<FILEARRAY[i].length(); j++){

                        current = FILEARRAY[i].charAt(j);

                        if(current != '\t'){
                            // add to ISBN
                            if(fieldCount == 0){
                                ISBN1 = ISBN1.concat(String.valueOf(current));
                            }
                            // add to title
                            else if(fieldCount == 1){
                                title = title.concat(String.valueOf(current));
                            }
                            // add to description
                            else if(fieldCount == 2){
                                description = description.concat(String.valueOf(current));
                            }
                            // add to price
                            else if(fieldCount == 3){
                                price = price.concat(String.valueOf(current));
                            }
                        }
                        else if(current == '\t'){
                            fieldCount++;
                        }

                    }
                    // add fields to returnArray
                    returnArray[0] = ISBN1;
                    returnArray[1] = title;
                    returnArray[2] = description;
                    returnArray[3] = price;
                }

                return returnArray;
            } else {
                /** Return error message */
                String[] error1 = new String[1];
                error1[0] = "File not read";
                return error1;
            }
        } else {
            /** Return error message */
            String[] error2 = new String[1];
            error2[0] = "Client not connected";
            return error2;
        }
    }

//   public static String[] getBookbyTitle(String Title) {
//        if (CLIENTCONNECTED == true) {
//            int successful = readFromFile(Title, CATEGORY,
//                    SERVICENAME);
//            if (successful == 0) {
//                String[] returnArray = new String[4];
//
//                // Loops through records
//                for(int i=0; i<FILEARRAY.length; i++){
//                    // Loops through fields in the record i
//                    char current;
//
//                    String ISBN1 = "";
//                    String title = "";
//                    String description = "";
//                    String price = "";
//
//                    int fieldCount = 0;
//                    for(int j=0; j<FILEARRAY[i].length(); j++){
//
//                        current = FILEARRAY[i].charAt(j);
//
//                        if(current != '\t'){
//                            // add to ISBN
//                            if(fieldCount == 0){
//                                ISBN1 = ISBN1.concat(String.valueOf(current));
//                            }
//                            // add to title
//                            else if(fieldCount == 1){
//                                title = title.concat(String.valueOf(current));
//                            }
//                            // add to description
//                            else if(fieldCount == 2){
//                                description = description.concat(String.valueOf(current));
//                            }
//                            // add to price
//                            else if(fieldCount == 3){
//                                price = price.concat(String.valueOf(current));
//                            }
//                        }
//                        else if(current == '\t'){
//                            fieldCount++;
//                        }
//
//                    }
//                    // add fields to returnArray
//                    returnArray[0] = ISBN1;
//                    returnArray[1] = title;
//                    returnArray[2] = description;
//                    returnArray[3] = price;
//                }
//
//                return returnArray;
//            } else {
//                /** Return error message */
//                String[] error1 = new String[1];
//                error1[0] = "File not read";
//                return error1;
//            }
//        } else {
//            /** Return error message */
//            String[] error2 = new String[1];
//            error2[0] = "Client not connected";
//            return error2;
//        }
//    }

    public static String[][] getBookbyTitle(String Title) {
        if (CLIENTCONNECTED == true) {
            int successful = readFromFile(Title, CATEGORY,
                    SERVICENAME);
            if (successful == 0) {
                String[][] returnArray = new String[FILEARRAY.length][4];

                // Loops through records
                for(int i=0; i<FILEARRAY.length; i++){
                    // Loops through fields in the record i
                    char current;

                    String ISBN = "";
                    String title = "";
                    String description = "";
                    String price = "";

                    int fieldCount = 0;
                    for(int j=0; j<FILEARRAY[i].length(); j++){

                        current = FILEARRAY[i].charAt(j);

                        if(current != '\t'){
                            // add to ISBN
                            if(fieldCount == 0){
                                ISBN = ISBN.concat(String.valueOf(current));
                            }
                            // add to title
                            else if(fieldCount == 1){
                                title = title.concat(String.valueOf(current));
                            }
                            // add to description
                            else if(fieldCount == 2){
                                description = description.concat(String.valueOf(current));
                            }
                            // add to price
                            else if(fieldCount == 3){
                                price = price.concat(String.valueOf(current));
                            }
                        }
                        else if(current == '\t'){
                            fieldCount++;
                        }

                    }
                    // add fields to returnArray
                    returnArray[i][0] = ISBN;
                    returnArray[i][1] = title;
                    returnArray[i][2] = description;
                    returnArray[i][3] = price;
                }

                return returnArray;
            } else {
                /** Return error message */
                String[][] error1 = new String[1][0];
                error1[0][0] = "File not read";
                return error1;
            }
        } else {
            /** Return error message */
            String[][] error2 = new String[1][0];
            error2[0][0] = "Client not connected";
            return error2;
        }
    }


    public static String deleteDB(String category){
        if (CLIENTCONNECTED == true) {
            int successful = deleteFile(category  + "Database", SERVICENAME);

            if (successful == 0) {
                /** Return confirmation message */
                return "Database deleted";
            } else {
                /** Return error message */
                return "Database not found";
            }
        } else {
            /** Return error message */
            return "Client not connected";
        }
    }
}

